package com.cvtech.processing;

import java.io.File;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DocumentParser {

	private Document fichierCompetences;
	private DocumentBuilder documentBuilder;
	private ArrayList<String> nomsCv;
	
	public DocumentParser(String adresseFichierCompetences) {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			documentBuilder = dbf.newDocumentBuilder ();
			fichierCompetences = documentBuilder.parse(new File(adresseFichierCompetences));
			
			nomsCv = genererListeCv();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	private ArrayList<String> genererListeCv(){

		Pattern pattern = Pattern.compile("P[0-9]{8}.xml");
        String [] string = new File("./CV etudiants/").list();
        ArrayList<String> listeFichiers = new ArrayList<String>();
        
        for (int i=0; i<string.length;i++) {
            Matcher m = pattern.matcher(string[i]);
            if ( m.matches()) {
            	listeFichiers.add("./CV etudiants/" + string[i]);
            }
        }
        
        return listeFichiers;
    }

	@SuppressWarnings("finally")
	public Document genererFichierPersonnes() {
		Document fichierPersonnes = documentBuilder.newDocument();
		try {
			NodeList listeCompetencesGenerales = fichierCompetences.getElementsByTagName("Competence");
			Node noeudPersonnes = fichierPersonnes.createElement("Personnes");
			
			for (int i = 0; i < nomsCv.size(); i++) {
				Document fichierCv = documentBuilder.parse(new File(nomsCv.get(i)));
				
				// Creation de l'�lement CV
				Element elementCv = fichierPersonnes.createElement("CV");
				
				// Creation du noeud nom, ajout de sa valeur
				Node noeudNom = fichierPersonnes.createElement("Nom");
				noeudNom.setTextContent(fichierCv.getElementsByTagName("Nom").item(0).getTextContent());
				
				// Creation du noeud pr�nom, ajout de sa valeur
				Node noeudPrenom = fichierPersonnes.createElement("Prenom");
				noeudPrenom.setTextContent(fichierCv.getElementsByTagName("Prenom").item(0).getTextContent());
				
				// Creation du noeud NomFichier
				String nomFichier = nomsCv.get(i).split("/")[2];
				Node noeudNomFichier = fichierPersonnes.createElement("NomFichier");
				noeudNomFichier.setTextContent(nomFichier);
				
				// Ajout des �l�ments cr�es
				elementCv.appendChild(noeudNom);
				elementCv.appendChild(noeudPrenom);
				elementCv.appendChild(noeudNomFichier);
				
				// Creation de l'attribut idCV
				String cvId = fichierCv.getElementsByTagName("CV").item(0).getAttributes().getNamedItem("idP").getTextContent();
				elementCv.setAttribute("idCV", cvId);
				
				Element elementCompetencesPersonne = fichierPersonnes.createElement("Competences");
				
				// Recup�ration des comp�tences du Cv
				NodeList listeCompetencesCv = fichierCv.getElementsByTagName("Comp");
				
				for (int j = 0; j < listeCompetencesCv.getLength(); j ++) {
					// Creation d'un �l�ment Comp pour la personne en cours
					Element elementCompPersonne = fichierPersonnes.createElement("Comp");
					
					Node competenceCv = listeCompetencesCv.item(j);
					
					// Initialisation de l'id de la comp�tence
					String compCvId = "";
					
					// R�cup�ration de l'ID de la comp�tence actuelle
					for (int k = 0; k < listeCompetencesGenerales.getLength(); k++) {
						Node compGenerale = listeCompetencesGenerales.item(k);
						
						String nomCompetenceGenerale = compGenerale.getFirstChild().getTextContent();
						String nomCompetenceCv = competenceCv.getFirstChild().getTextContent();

						if (nomCompetenceGenerale.equalsIgnoreCase(nomCompetenceCv)) {
							compCvId = compGenerale.getAttributes().getNamedItem("idC").getTextContent();
							break;
						}
					}
				
					elementCompPersonne.setAttribute("idC", compCvId);
					elementCompetencesPersonne.appendChild(elementCompPersonne);
				}
				elementCv.appendChild(elementCompetencesPersonne);
				noeudPersonnes.appendChild(elementCv);
			}
			fichierPersonnes.appendChild(noeudPersonnes);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return fichierPersonnes;
		}
	}
	
	public void mettreAJourFichierCompetencesGeneraleViaCV(String nomFichier) {
		try {
			// Ouverture du document et r�cup�ration des comp�tences
			Document fichierCv = documentBuilder.parse(new File(nomFichier));
			NodeList competencesCv = fichierCv.getElementsByTagName("Comp");
			NodeList competencesGenerales = fichierCompetences.getElementsByTagName("Competence");
			
			// Initialisation du compteur concernant l'ajout de nouveaux Id
			int idValue = competencesGenerales.getLength();
			
			// Comparaison des comp�tences avec le fichier des comp�tences g�n�rales
			for (int i = 0; i < competencesCv.getLength(); i++) {
				boolean existe = false;
				Node competence = competencesCv.item(i);
				
				for (int j = 0; j < competencesGenerales.getLength(); j++) {
					Node competenceGenerale = competencesGenerales.item(j);
					String nomCompetenceGenerale = competenceGenerale.getFirstChild().getTextContent();
					if (nomCompetenceGenerale.equalsIgnoreCase(competence.getTextContent())) {
						existe = true;
						break;
					}
				}
				
				if (existe == false) {
					// Cr�ation du premier �l�ment : Nom comp�tence
					Node nomCompetence = fichierCompetences.createElement("Nom");
					nomCompetence.setTextContent(competence.getFirstChild().getTextContent());
					
					// Cr�ation du second �l�ment : Type comp�tence
					Node typeCompetence = fichierCompetences.createElement("Type");
					typeCompetence.setTextContent(competence.getAttributes().getNamedItem("type").getTextContent());
					
					// On incr�mente l'id de la comp�tence
					idValue++;
					
					// Cr�ation de l'�l�ment Comp�tence
					Element competenceAjoutee = fichierCompetences.createElement("Competence");
					competenceAjoutee.appendChild(nomCompetence);
					competenceAjoutee.appendChild(typeCompetence);
					competenceAjoutee.setAttribute("idC", "" + idValue + "");
					fichierCompetences.getLastChild().appendChild(competenceAjoutee);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void serialize(Document document, String fichier) {
        try {
            Source source = new DOMSource(document);
            StreamResult resultat = new StreamResult(fichier);
            TransformerFactory fabrique = TransformerFactory.newInstance();
            Transformer transformer = fabrique.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.transform(source, resultat);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
	
	/* GETTERS AND SETTERS */

	public Document getFichierCompetences() {
		return fichierCompetences;
	}

	public void setFichierCompetences(Document fichierCompetences) {
		this.fichierCompetences = fichierCompetences;
	}

	public DocumentBuilder getDocumentBuilder() {
		return documentBuilder;
	}

	public void setDocumentBuilder(DocumentBuilder documentBuilder) {
		this.documentBuilder = documentBuilder;
	}

	public ArrayList<String> getNomsCv() {
		return nomsCv;
	}

	public void setNomsCv(ArrayList<String> nomsCv) {
		this.nomsCv = nomsCv;
	}
	
	public static void main(String[] args) {
		DocumentParser docP = new DocumentParser("Competences.xml");
		for (int i = 0; i < docP.getNomsCv().size(); i++) {
			docP.mettreAJourFichierCompetencesGeneraleViaCV(docP.getNomsCv().get(i));
		}
		
		Document personnes = docP.genererFichierPersonnes();
		DocumentParser.serialize(docP.getFichierCompetences(), "TestCOMP.xml");	
		DocumentParser.serialize(personnes, "personnes.xml");
	}
}
